package com.seguriapp.entitieslist.gwt.server;

import static com.google.common.collect.Lists.newArrayList;

import java.util.List;

import net.customware.gwt.dispatch.server.ExecutionContext;
import net.customware.gwt.dispatch.shared.DispatchException;
import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.restlet.data.MediaType;
import org.restlet.resource.ClientResource;

import com.seguriapp.common.config.GlobalConfigLoader;
import com.seguriapp.common.gwt.server.AbstractSeguriAppHandler;
import com.seguriapp.entities.District;
import com.seguriapp.entities.SeguriAppEntity;
import com.seguriapp.entitieslist.gwt.shared.GetEntitiesListAction;
import com.seguriapp.entitieslist.gwt.shared.GetEntitiesListResult;

public class GetEntitiesListHandler extends AbstractSeguriAppHandler<GetEntitiesListAction, GetEntitiesListResult> {

  private static final Logger LOGGER = Logger.getLogger(GetEntitiesListHandler.class);

  public Class<GetEntitiesListAction> getActionType() {
    return GetEntitiesListAction.class;
  }

  public GetEntitiesListResult execute(final GetEntitiesListAction action, final ExecutionContext context) throws DispatchException {

    final GetEntitiesListResult result = new GetEntitiesListResult();
    try {
      final String serverUrl = GlobalConfigLoader.getInstance().getGlobalConfig().getBackEndUrl();
      final String url = serverUrl.concat(GlobalConfigLoader.getInstance().getGlobalConfig().getEntitiesList());
      final ClientResource resource = new ClientResource(url);
      final String entityTypesListJs = resource.post(convertDataToJsonString(action), MediaType.TEXT_PLAIN).getText();
      LOGGER.info("Data received : \n" + entityTypesListJs);
      result.setEntitiesList(getJsonDataFromString(entityTypesListJs));
      result.setCurrentPage(action.getPage());
      result.setMaxPages(GlobalConfigLoader.getInstance().getGlobalConfig().getMaxPages());
      result.setTotalPages(getJsonTotalPages(entityTypesListJs));
      result.setDefaultLatitude(GlobalConfigLoader.getInstance().getGlobalConfig().getDefaultLatitude());
      result.setDefaultLongitude(GlobalConfigLoader.getInstance().getGlobalConfig().getDefaultLongitude());
    } catch (Exception e) {
      LOGGER.error("Error obtaining the initial data \n", e);
    }
    return result;
  }

  private String convertDataToJsonString(final GetEntitiesListAction action) {
    final JSONObject obj = new JSONObject();
    try {
      obj.put("entityTypeId", action.getEntityTypeId());
      obj.put("page", action.getPage());
      obj.put("pageSize", GlobalConfigLoader.getInstance().getGlobalConfig().getPageSize());
      obj.put("ascending", action.isAscending());
      obj.put("columnSort", action.getColumnSort());
      if (action.getDistrictsList() != null && !action.getDistrictsList().isEmpty()) {
        String districtsIdsList = StringUtils.EMPTY;
        for (final Long id : action.getDistrictsList()) {
          districtsIdsList += id.toString() + ",";
        }
        obj.put("districtsIdsList", districtsIdsList.substring(0, districtsIdsList.length() - 1));
      }
    } catch (JSONException e) {
      LOGGER.error(e.getStackTrace());
    }
    LOGGER.info("Sending Data : \n" + obj.toString());
    return obj.toString();
  }

  private List<SeguriAppEntity> getJsonDataFromString(final String menuLinksListJs) {
    final List<SeguriAppEntity> entityTypesList = newArrayList();
    final JSONObject root = JSONObject.fromObject(menuLinksListJs);
    JSONArray dataArray = null;
    JSONObject jo = null;
    if (root.has("entitiesList")) {
      dataArray = root.getJSONArray("entitiesList");
      if (dataArray != null) {
        for (int i = 0; i < dataArray.size(); i++) {
          jo = dataArray.getJSONObject(i);
          final SeguriAppEntity entity = processjSONObject(jo);
          if (entity != null){
            entityTypesList.add(entity);
          }
        }
      }
    }
    return entityTypesList;
  }

  private SeguriAppEntity processjSONObject(final JSONObject jo) {
    if (jo.has("id") && jo.has("title") && jo.has("address") && jo.has("latitude") && jo.has("longitude") && jo.has("district")) {
      final SeguriAppEntity entity = new SeguriAppEntity();
      entity.setId(jo.getLong("id"));
      entity.setTitle(jo.getString("title"));
      entity.setAddress(jo.getString("address"));
      entity.setLatitude(jo.getDouble("latitude"));
      entity.setLongitude(jo.getDouble("longitude"));
      entity.setPhone(jo.getString("phone"));
      final JSONObject joDistrict = jo.getJSONObject("district");
      final District district = new District();
      district.setId(joDistrict.getLong("id"));
      district.setName(joDistrict.getString("name"));
      entity.setDistrict(district);
      return entity;
    }
    return null;
  }

  private long getJsonTotalPages(final String complaintListJs) {
    long totalPages = 0;
    final JSONObject root = JSONObject.fromObject(complaintListJs);
    if (root.has("totalPages")) {
      totalPages = root.getLong("totalPages");
    }
    return totalPages;
  }

}
